home *** CD-ROM | disk | FTP | other *** search
/ Cre@te Online 2000 December / Cre@teOnline CD05.iso / MacSoft / XML Authority.sea / XML Authority / Required / ccs_util.jar / regex / RegExpParser.class (.txt) < prev    next >
Encoding:
Java Class File  |  1999-12-09  |  6.2 KB  |  355 lines

  1. package regex;
  2.  
  3. import java.util.Hashtable;
  4.  
  5. class RegExpParser {
  6.    private static final int TK_END = 0;
  7.    private static final int TK_CHAR = 1;
  8.    private static final int TK_CHARCLASS = 2;
  9.    private static final int TK_UNION = 10;
  10.    private static final int TK_LPAR = 11;
  11.    private static final int TK_RPAR = 12;
  12.    private static final int TK_CLOSURE = 13;
  13.    private static final int TK_PLUS = 14;
  14.    private static final int TK_QUESTION = 15;
  15.    private static final int TK_ANYCHAR = 16;
  16.    private static final int TK_LBRA = 17;
  17.    private static final int TK_LBRANEG = 18;
  18.    private static final int TK_RBRA = 19;
  19.    private static final int TK_LHEAD = 20;
  20.    private static final int TK_LTAIL = 21;
  21.    private static final char CHAR_VL = '|';
  22.    private static final char CHAR_LPAR = '(';
  23.    private static final char CHAR_RPAR = ')';
  24.    private static final char CHAR_ASTERISK = '*';
  25.    private static final char CHAR_PLUS = '+';
  26.    private static final char CHAR_QUESTION = '?';
  27.    private static final char CHAR_DOT = '.';
  28.    private static final char CHAR_LBRA = '[';
  29.    private static final char CHAR_RBRA = ']';
  30.    private static final char CHAR_CARET = '^';
  31.    private static final char CHAR_DOLLAR = '$';
  32.    private static final char CHAR_MINUS = '-';
  33.    private static final char CHAR_BKSLASH = '\\';
  34.    private static final String MSG_INVALID_ESCAPE = "Invalid escape character.";
  35.    private static final String MSG_INVALID_CHARRANGE = "Invalid character range.";
  36.    private static final String MSG_RBRA_EXPECTED = "\"]\" is expected.";
  37.    private static final String MSG_RPAR_EXPECTED = "\")\" is expected.";
  38.    private static final String MSG_CHAR_EXPECTED = "Normal character is expected.";
  39.    private int currentToken;
  40.    private Chars tokenChars;
  41.    private String strbuff = "";
  42.    private int pstr = 0;
  43.    private boolean inCharClass = false;
  44.    private static Hashtable escapeTable = new Hashtable();
  45.  
  46.    private int getTokenCC() throws RegExpSyntaxException {
  47.       if (this.pstr == this.strbuff.length()) {
  48.          throw new RegExpSyntaxException("\"]\" is expected.");
  49.       } else {
  50.          char var1 = this.strbuff.charAt(this.pstr++);
  51.          if (var1 == ']') {
  52.             this.currentToken = 19;
  53.          } else {
  54.             if (var1 == '\\') {
  55.                if (this.pstr == this.strbuff.length()) {
  56.                   throw new RegExpSyntaxException("Illegal escape sequense.");
  57.                }
  58.  
  59.                var1 = this.strbuff.charAt(this.pstr++);
  60.             }
  61.  
  62.             this.currentToken = 1;
  63.             char var2 = this.strbuff.charAt(this.pstr++);
  64.             if (var2 == '-') {
  65.                if (this.pstr == this.strbuff.length()) {
  66.                   throw new RegExpSyntaxException("\"]\" is expected.");
  67.                }
  68.  
  69.                char var3 = this.strbuff.charAt(this.pstr++);
  70.                if (var3 == ']') {
  71.                   this.pstr -= 2;
  72.                   this.tokenChars = new Chars(var1);
  73.                } else {
  74.                   if (var3 == '\\') {
  75.                      if (this.pstr == this.strbuff.length()) {
  76.                         throw new RegExpSyntaxException("Invalid escape character.");
  77.                      }
  78.  
  79.                      var3 = this.strbuff.charAt(this.pstr++);
  80.                   }
  81.  
  82.                   this.currentToken = 2;
  83.                   if (var1 > var3) {
  84.                      throw new RegExpSyntaxException("Invalid character range.");
  85.                   }
  86.  
  87.                   this.tokenChars = new Chars(var1, var3);
  88.                }
  89.             } else {
  90.                this.pstr += -1;
  91.                this.tokenChars = new Chars(var1);
  92.             }
  93.          }
  94.  
  95.          return this.currentToken;
  96.       }
  97.    }
  98.  
  99.    private RTree term() throws RegExpSyntaxException {
  100.       RTree var1;
  101.       if (this.currentToken != 10 && this.currentToken != 12 && this.currentToken != 0) {
  102.          for(var1 = this.factor(); this.currentToken != 10 && this.currentToken != 12 && this.currentToken != 0; var1 = new RTree(2, var1, this.factor())) {
  103.          }
  104.       } else {
  105.          var1 = new RTree(0, (RTree)null, (RTree)null);
  106.       }
  107.  
  108.       return var1;
  109.    }
  110.  
  111.    private RTree charClass() throws RegExpSyntaxException {
  112.       this.nextToken();
  113.       if (this.currentToken == 19) {
  114.          throw new RegExpSyntaxException("Invalid character class.");
  115.       } else {
  116.          RTree var1 = new RTree(this.tokenChars);
  117.          this.nextToken();
  118.  
  119.          while(this.currentToken != 19) {
  120.             var1 = new RTree(3, var1, new RTree(this.tokenChars));
  121.             this.nextToken();
  122.          }
  123.  
  124.          return var1;
  125.       }
  126.    }
  127.  
  128.    private void initialize(String var1) throws RegExpSyntaxException {
  129.       this.strbuff = this.processEscape(var1);
  130.       this.pstr = 0;
  131.       this.nextToken();
  132.    }
  133.  
  134.    private RTree negativeCharClass() throws RegExpSyntaxException {
  135.       this.nextToken();
  136.       if (this.currentToken == 19) {
  137.          throw new RegExpSyntaxException("Invalid character class.");
  138.       } else {
  139.          RTree var1 = new RTree(new Chars('\u0000', '\uffff'));
  140.  
  141.          while(this.currentToken != 19) {
  142.             var1.removeChars(this.tokenChars);
  143.             this.nextToken();
  144.          }
  145.  
  146.          return var1;
  147.       }
  148.    }
  149.  
  150.    public RTree parse(String var1) throws RegExpSyntaxException {
  151.       this.initialize(var1);
  152.       RTree var2 = this.regexp();
  153.       if (this.currentToken != 0) {
  154.          throw new RegExpSyntaxException("Extra character at end of pattren.");
  155.       } else {
  156.          return var2;
  157.       }
  158.    }
  159.  
  160.    private void nextToken() throws RegExpSyntaxException {
  161.       if (this.inCharClass) {
  162.          int var1 = this.getTokenCC();
  163.          if (var1 == 19) {
  164.             this.inCharClass = false;
  165.          }
  166.       } else {
  167.          int var2 = this.getTokenStd();
  168.          if (var2 == 17 || var2 == 18) {
  169.             this.inCharClass = true;
  170.          }
  171.       }
  172.  
  173.    }
  174.  
  175.    public RegExpParser() {
  176.    }
  177.  
  178.    private RTree factor() throws RegExpSyntaxException {
  179.       RTree var1 = this.primary();
  180.       if (this.currentToken == 13) {
  181.          var1 = new RTree(4, var1, (RTree)null);
  182.          this.nextToken();
  183.       } else if (this.currentToken == 14) {
  184.          var1 = new RTree(2, var1, new RTree(4, var1, (RTree)null));
  185.          this.nextToken();
  186.       } else if (this.currentToken == 15) {
  187.          var1 = new RTree(3, var1, new RTree(0, (RTree)null, (RTree)null));
  188.          this.nextToken();
  189.       }
  190.  
  191.       return var1;
  192.    }
  193.  
  194.    private String processEscape(String var1) {
  195.       String var6 = "";
  196.  
  197.       for(int var2 = 0; var2 < var1.length(); ++var2) {
  198.          char var3;
  199.          if ((var3 = var1.charAt(var2)) == '\\') {
  200.             ++var2;
  201.             String var5 = var1.substring(var2, var2 + 1);
  202.             String var4 = (String)escapeTable.get(var5);
  203.             if (var4 == null) {
  204.                var6 = var6 + "\\" + var5;
  205.             } else {
  206.                var6 = var6 + var4;
  207.             }
  208.          } else {
  209.             var6 = var6 + var3;
  210.          }
  211.       }
  212.  
  213.       return var6;
  214.    }
  215.  
  216.    private int getTokenStd() throws RegExpSyntaxException {
  217.       if (this.pstr == this.strbuff.length()) {
  218.          this.currentToken = 0;
  219.       } else {
  220.          char var1 = this.strbuff.charAt(this.pstr++);
  221.          switch (var1) {
  222.             case '$':
  223.                this.currentToken = 21;
  224.                this.tokenChars = new Chars(var1);
  225.                break;
  226.             case '(':
  227.                this.currentToken = 11;
  228.                break;
  229.             case ')':
  230.                this.currentToken = 12;
  231.                break;
  232.             case '*':
  233.                this.currentToken = 13;
  234.                break;
  235.             case '+':
  236.                this.currentToken = 14;
  237.                break;
  238.             case '.':
  239.                this.currentToken = 16;
  240.                break;
  241.             case '?':
  242.                this.currentToken = 15;
  243.                break;
  244.             case '[':
  245.                if (this.pstr == this.strbuff.length()) {
  246.                   throw new RegExpSyntaxException("\"]\" is expected.");
  247.                }
  248.  
  249.                var1 = this.strbuff.charAt(this.pstr++);
  250.                if (var1 == '^') {
  251.                   this.currentToken = 18;
  252.                } else {
  253.                   this.pstr += -1;
  254.                   this.currentToken = 17;
  255.                }
  256.                break;
  257.             case '\\':
  258.                if (this.pstr == this.strbuff.length()) {
  259.                   throw new RegExpSyntaxException("Invalid escape character.");
  260.                }
  261.  
  262.                this.currentToken = 1;
  263.                this.tokenChars = new Chars(this.strbuff.charAt(this.pstr++));
  264.                break;
  265.             case '^':
  266.                this.currentToken = 20;
  267.                this.tokenChars = new Chars(var1);
  268.                break;
  269.             case '|':
  270.                this.currentToken = 10;
  271.                break;
  272.             default:
  273.                this.currentToken = 1;
  274.                this.tokenChars = new Chars(var1);
  275.          }
  276.       }
  277.  
  278.       return this.currentToken;
  279.    }
  280.  
  281.    static {
  282.       escapeTable.put("0", "\u0000");
  283.       escapeTable.put("b", "\b");
  284.       escapeTable.put("t", "\t");
  285.       escapeTable.put("r", "\r");
  286.       escapeTable.put("n", "\n");
  287.       escapeTable.put("d", "[0-9]");
  288.       escapeTable.put("D", "[^0-9]");
  289.       escapeTable.put("s", "[ \t\r\n]");
  290.       escapeTable.put("S", "[^ \t\r\n]");
  291.       escapeTable.put("w", "[0-9A-Z_a-z]");
  292.       escapeTable.put("W", "[^0-9A-Z_a-z]");
  293.    }
  294.  
  295.    private RTree primary() throws RegExpSyntaxException {
  296.       RTree var1;
  297.       switch (this.currentToken) {
  298.          case 1:
  299.             var1 = new RTree(this.tokenChars);
  300.             this.nextToken();
  301.             break;
  302.          case 11:
  303.             this.nextToken();
  304.             var1 = this.regexp();
  305.             if (this.currentToken != 12) {
  306.                throw new RegExpSyntaxException("\")\" is expected.");
  307.             }
  308.  
  309.             this.nextToken();
  310.             break;
  311.          case 16:
  312.             var1 = new RTree(new Chars('\u0000', '\uffff'));
  313.             this.nextToken();
  314.             break;
  315.          case 17:
  316.             var1 = this.charClass();
  317.             if (this.currentToken != 19) {
  318.                throw new RegExpSyntaxException("\"]\" is expected.");
  319.             }
  320.  
  321.             this.nextToken();
  322.             break;
  323.          case 18:
  324.             var1 = this.negativeCharClass();
  325.             if (this.currentToken != 19) {
  326.                throw new RegExpSyntaxException("\"]\" is expected.");
  327.             }
  328.  
  329.             this.nextToken();
  330.             break;
  331.          case 20:
  332.             var1 = new RTree(5, this.tokenChars, (RTree)null, (RTree)null);
  333.             this.nextToken();
  334.             break;
  335.          case 21:
  336.             var1 = new RTree(6, this.tokenChars, (RTree)null, (RTree)null);
  337.             this.nextToken();
  338.             break;
  339.          default:
  340.             throw new RegExpSyntaxException("Normal character is expected.");
  341.       }
  342.  
  343.       return var1;
  344.    }
  345.  
  346.    private RTree regexp() throws RegExpSyntaxException {
  347.       RTree var1;
  348.       for(var1 = this.term(); this.currentToken == 10; var1 = new RTree(3, var1, this.term())) {
  349.          this.nextToken();
  350.       }
  351.  
  352.       return var1;
  353.    }
  354. }
  355.